<template>
  <div class="dyh">
    <q-splitter
      v-model="splitterModel"
      separator-style="width: 0"
      style="height: calc(100vh - 33px)"
    >
      <template v-slot:before>
        <q-splitter
          v-model="leftModel"
          horizontal
          separator-class="bg-red"
          separator-style="height: 0"
        >
          <template v-slot:before>
            <div class="q-px-xs">
              <q-bar
                style="height: 36px"
                class="text-weight-bold flex justify-center text-body1 sticky text-center text-uppercase dyh rounded-borders glass-10"
              >
                <div class="text-caption bg-clip-text bg-red-love text-no-wrap">
                  {{ $t('tableTitle') }}
                </div>
              </q-bar>
              <q-list class="q-gutter-y-xs q-py-xs">
                <q-slide-item
                  v-for="(table, index) in useProjectStore().project?.out
                    ?.tables"
                  :key="index"
                  bordered
                  class="full-width rounded-borders text-purple-7"
                  dense
                  left-color="red"
                  right-color="purple"
                  @click="selectTable(table)"
                >
                  <q-item
                    :active="tableSelected === table"
                    active-class="text-red bg-bottom-border-red "
                    class="rounded-borders bg-gradation-20deg-e9defa-fbfcdb overflow-hidden transition-all"
                    dense
                  >
                    <q-item-section class="text-no-wrap">
                      {{ table }}
                    </q-item-section>
                  </q-item>
                </q-slide-item>
              </q-list>
            </div>
          </template>

          <template v-slot:after>
            <q-splitter
              v-model="leftInsideModel"
              horizontal
              separator-class="bg-red"
              separator-style="height: 0"
            >
              <template v-slot:before>
                <q-card
                  bordered
                  class="q-my-xs q-mx-xs"
                  flat
                  style="height: calc(100% - 8px); width: calc(100% - 8px)"
                >
                  <q-bar
                    style="height: 26px"
                    class="text-weight-thin glass-10 text-uppercase flex row no-wrap overflow-hidden"
                    header
                  >
                    <div class="bg-clip-text bg-red-love">
                      {{ $t('tableAfter') }}
                    </div>
                    <div class="bg-clip-text bg-gradation-120deg-a6c0fe-f68084">
                      {{ tableSelected }}
                    </div>
                    <div class="bg-clip-text text-no-wrap bg-red-love">
                      {{ $t('tableSuffix') }}
                    </div>
                    <q-space />
                    <div>YML</div>
                  </q-bar>
                  <ql-editor
                    :content="tableContentEditor"
                    editor-id="tableContent"
                    style="
                      width: calc(100%);
                      height: calc(100% - 26px);
                      overflow: hidden;
                    "
                    temp-type="yaml"
                  />
                </q-card>
              </template>

              <template v-slot:after>
                <q-card
                  bordered
                  class="q-mb-xs q-ml-xs bg-transparent"
                  flat
                  style="height: calc(100% - 8px); width: calc(100% - 8px)"
                >
                  <q-bar
                    style="height: 26px"
                    class="text-caption glass-10 flex row no-wrap"
                  >
                    <div class="bg-clip-text bg-red-love text-no-wrap">
                      {{ $t('defineArgs') }}
                    </div>
                    <q-space />
                    <div>JS</div>
                  </q-bar>
                  <ql-editor
                    editor-id="defineEditor"
                    style="
                      width: calc(100%);
                      height: calc(100% - 26px);
                      overflow: hidden;
                    "
                    :template-id="configStore.project?.out?.define"
                    temp-type="javascript"
                  />
                </q-card>
              </template>
            </q-splitter>
          </template>
        </q-splitter>
      </template>

      <template v-slot:after>
        <q-splitter
          v-model="insideModel"
          horizontal
          separator-class="bg-red"
          separator-style="height: 0"
        >
          <template v-slot:before>
            <div style="height: 100%; width: 100%; overflow: hidden">
              <q-bar
                style="height: 36px"
                class="glass-10 flex rounded-borders no-wrap overflow-hidden"
              >
                <q-btn
                  :loading="genStatus"
                  class="bg-red-love q-mr-xs text-weight-thin text-white"
                  dense
                  flat
                  icon="play_arrow"
                  size="12px"
                  @click="generate"
                >
                  <q-tooltip delay="600">
                    {{ $t('genPage') }}
                  </q-tooltip>
                  <template v-slot:loading>
                    <q-spinner-hourglass class="on-left absolute-center" />
                  </template>
                </q-btn>

                <q-btn
                  class="text-white bg-gradation-120deg-f093fb-f5576c define text-no-wrap"
                  dense
                  size="12px"
                  flat
                  :label="$t('testBtn')"
                  @click="test2"
                />
                <!-- ...... -->

                <q-separator
                  class="q-mx-sm q-my-sm bg-red-love"
                  size="2px"
                  vertical
                />
                <q-input
                  v-model="renderDebounce"
                  borderless
                  dense
                  :label="$t('render') + '/ms'"
                  style="min-width: 50px; max-width: 80px"
                />
                <q-space />
                <q-tabs
                  dense
                  outside-arrows
                  mobile-arrows
                  style="width: 100%"
                  inline-label
                  class=""
                  v-model="tab"
                  shrink
                >
                  <q-tab
                    v-for="(item, index) in useProjectStore().project?.mapper"
                    :key="index"
                    :class="{
                      'text-red': tab === item.templateId,
                    }"
                    :label="item.name"
                    :name="item.templateId"
                    class="q-mx-xs q-px-sm text-subtitle1"
                  />
                </q-tabs>
              </q-bar>
              <q-card
                bordered
                class="q-mt-xs bg-transparent"
                flat
                style="height: calc(100% - 44px); width: calc(100% - 4px)"
              >
                <ql-editor
                  :on-chang-content="onTemplateContentChange"
                  :template-id="tab"
                  ref="templateEditor"
                  :debounce="renderDebounce"
                  editor-id="templateEditorId"
                />
              </q-card>
            </div>
          </template>

          <template v-slot:after>
            <q-card
              bordered
              class="bg-transparent"
              flat
              style="height: calc(100% - 8px); width: calc(100% - 4px)"
            >
              <ql-editor
                :content="renderEditorContent"
                :temp-type="renderEditorType"
                editor-id="renderEditorId"
              >
              </ql-editor>
            </q-card>
          </template>
        </q-splitter>
      </template>
    </q-splitter>
  </div>
</template>
<script lang="ts" setup>
import { editor } from 'monaco-editor';
import { onMounted, Ref, ref, toRaw, watch } from 'vue';
import * as Yaml from 'js-yaml';
import { date, LocalStorage } from 'quasar';
import QlEditor from 'components/QlEditor.vue';
import { initDatabaseConnection } from 'src/api/DatabaseApi';
import { renderTemplateContent } from 'src/api/render';
import { useConfigStore } from 'stores/configStore';
import { Config, ConfigProject, Project } from 'src/types';
import { useGenStore } from 'stores/genStore';
import { useTemplateStore } from 'stores/templateStore';
import { useProjectStore } from 'stores/projectStore';

const tab: Ref<number> = ref(0);
const renderDebounce = ref(10);
const splitterModel = ref(33);
const insideModel = ref(33);
const leftModel = ref(25);
const leftInsideModel = ref(60);
const tableSelected = ref('');
const renderEditorContent = ref('');
const renderEditorType = ref('');
const tableContentEditor = ref('');
let tableContentObject = {};
const configStore = ref({} as ConfigProject);
let editor: editor.IStandaloneCodeEditor | null = null;
const templateEditor: Ref<editor.IStandaloneCodeEditor | null> = ref(null);
const onTemplateContentChange = async (content: string) => {
  renderEditorContent.value = await renderTemplateContent(content, {
    ...tableContentObject[tableSelected.value],
    ...new Function(
      'return' +
        (
          await useTemplateStore().getTemplateContentById(
            Number.parseInt(useProjectStore().project.out?.define as string)
          )
        ).content
    )(),
  });
  console.log(renderEditorContent.value);
  renderEditorType.value = await templateEditor.value?.getQlEditorType();
};
watch(
  tableSelected,
  () => {
    refreshRenderContent();
  },
  { deep: true }
);
const refreshRenderContent = async () => {
  tableContentEditor.value = Yaml.dump(tableContentObject[tableSelected.value]);
  renderEditorContent.value = await renderTemplateContent(
    templateEditor.value?.getEditorContent(),
    {
      ...tableContentObject[tableSelected.value],
      ...new Function(
        'return' +
          (
            await useTemplateStore().getTemplateContentById(
              Number.parseInt(useProjectStore().project.out?.define as string)
            )
          ).content
      )(),
    }
  );
  renderEditorType.value = await templateEditor.value?.getQlEditorType();
};
const genStatus = ref(false);
// 生成代码
const generate = async () => {
  genStatus.value = true;
  await useGenStore().gen();
  genStatus.value = false;
};

const selectTable = async (table: string) => {
  tableSelected.value = table;
};
window.DateFormat = (format: string) => {
  return date.formatDate(new Date(), format);
};
watch(renderDebounce, () => {
  LocalStorage.set('renderDebounce', toRaw(renderDebounce.value));
});
onMounted(async () => {
  configStore.value = {
    ...((await useConfigStore().config) as Config),
    project: (await useProjectStore().project) as Project,
  };
  await initDatabaseConnection(
    toRaw(useProjectStore().project.datasource.find((i) => i.selected === true))
  );
  tab.value = configStore.value.project?.mapper[0]?.templateId || 0;
  tableContentObject = await useGenStore().getTablesData();
  tableSelected.value = configStore.value.project?.out?.tables[0];
});
const annotationRegex = /@Mapper([\s\S]*?)}/;
const getCodeBeforeBracket = (code: string) => {
  let bracketIndex = code.indexOf('{');

  if (bracketIndex === -1) {
    return '';
  }

  let annotationMatches = code.match(annotationRegex);
  if (annotationMatches === null) {
    return '';
  }

  return (
    annotationMatches.join('') +
    code.substring(
      annotationMatches[annotationMatches.length - 1].length,
      bracketIndex
    )
  );
};
const test2 = () => {
  // const element = document.querySelectorAll('.define') as HTMLElement[];
  // console.log(element);
  // element.forEach((i) => {
  //   i.style.backgroundColor = 'green';
  // });

  // let foo = `public boolean saveOne(CmsDatasourceConfigDTO dto) {
  //                   return this.save(CmsDatasourceConfigConvertor.INSTANCE.toEntity(dto));
  //               }`;
  // console.log(renderEditorContent.value.lastIndexOf('}'));
  // let tempArr = renderEditorContent.value.split('')
  // //todo 把文件中的方法插入方法封装进gen store中
  // tempArr[renderEditorContent.value.lastIndexOf('}')] = foo+'\n}'
  // console.log(tempArr.join(''));

  // const str = 'public class CmsDatasourceConfigController {';
  // const regex = /public class\s+(.*?)\s*\{/;
  // const match = regex.exec(str);
  // if (match) {
  //   console.log(match[1]);
  // } else {
  //   console.log('No match found');
  // }=
  // console.log(renderEditorContent.value);
  // const regex = /public CommonResult([\s\S]*)\}/;
  // const match = regex.exec(renderEditorContent.value);
  // if (match) {
  //   console.log(match[0]);
  // } else {
  //   console.log('No match found');
  // }
  let leftIndexes = [];
  let rightIndexes = [];
  let rightIndex = renderEditorContent.value.indexOf('}');
  let leftIndex = renderEditorContent.value.indexOf('{');
  while (rightIndex > 0) {
    rightIndexes.push(rightIndex);
    rightIndex = renderEditorContent.value.indexOf('}', rightIndex + 1);
  }
  while (leftIndex > 0) {
    leftIndexes.push(leftIndex);
    leftIndex = renderEditorContent.value.indexOf('{', leftIndex + 1);
  }
  console.log(rightIndexes);
  console.log(leftIndexes);
};
// const test2 = async () => {
//   // window
//   const ast = parse(renderEditorContent.value);
//   console.log(ast);
//
//   let classAst = {
//     className: ast.children.ordinaryCompilationUnit[0].children
//       .typeDeclaration[0].children.interfaceDeclaration
//       ? ast.children.ordinaryCompilationUnit[0].children.typeDeclaration[0]
//           .children.interfaceDeclaration[0].children
//           .normalInterfaceDeclaration[0].children.typeIdentifier[0].children
//           .Identifier[0].image
//       : ast.children.ordinaryCompilationUnit[0].children.typeDeclaration[0].children
//           .classDeclaration[0].children.normalClassDeclaration[0].children
//           .typeIdentifier[0].children.Identifier[0].image,
//     functions: [] as { name: string; return: string }[],
//     fields: [] as { name: string; type: string }[],
//   };
//   if (
//     ast.children.ordinaryCompilationUnit[0].children.typeDeclaration[0].children
//       .interfaceDeclaration
//   ) {
//     for (const astElement of ast.children.ordinaryCompilationUnit[0].children
//       .typeDeclaration[0].children.interfaceDeclaration[0].children
//       .normalInterfaceDeclaration[0].children.interfaceBody[0].children
//       .interfaceMemberDeclaration) {
//       const item = astElement;
//       console.log(item);
//       const funName =
//         item.children.interfaceMethodDeclaration[0].children.methodHeader[0]
//           .children.methodDeclarator[0].children.Identifier[0].image;
//       const funReturn = item.children.interfaceMethodDeclaration[0].children
//         .methodHeader[0].children.result[0].children.unannType[0].children
//         .unannPrimitiveTypeWithOptionalDimsSuffix
//         ? item.children.interfaceMethodDeclaration[0].children.methodHeader[0]
//             .children.result[0].children.unannType[0].children
//             .unannPrimitiveTypeWithOptionalDimsSuffix[0].children
//             .unannPrimitiveType[0].children.Boolean[0].image
//         : item.children.interfaceMethodDeclaration[0].children.methodHeader[0]
//             .children.result[0].children.unannType[0].children
//             .unannReferenceType[0].children.unannClassOrInterfaceType[0]
//             .children.unannClassType[0].children.Identifier[0].image;
//       classAst.functions.push({
//         name: funName as string,
//         return: funReturn as string,
//       });
//     }
//   } else {
//     for (const astElement of ast.children.ordinaryCompilationUnit[0].children
//       .typeDeclaration[0].children.classDeclaration[0].children
//       .normalClassDeclaration[0].children.classBody[0].children
//       .classBodyDeclaration) {
//       const item = astElement;
//
//       if (item.children.classMemberDeclaration[0].children.methodDeclaration) {
//         const funName =
//           item.children.classMemberDeclaration[0].children.methodDeclaration[0]
//             .children.methodHeader[0].children.methodDeclarator[0].children
//             .Identifier[0].image;
//         const funReturn =
//           item.children.classMemberDeclaration[0].children.methodDeclaration[0]
//             .children.methodHeader[0].children.result[0].children.unannType[0]
//             .children.unannReferenceType[0].children
//             .unannClassOrInterfaceType[0].children.unannClassType[0].children
//             .Identifier[0].image;
//         classAst.functions.push({
//           name: funName as string,
//           return: funReturn as string,
//         });
//       } else {
//         const type =
//           item.children.classMemberDeclaration[0].children.fieldDeclaration[0]
//             .children.unannType[0].children.unannReferenceType[0].children
//             .unannClassOrInterfaceType[0].children.unannClassType[0].children
//             .Identifier[0].image;
//
//         const name =
//           item.children.classMemberDeclaration[0].children.fieldDeclaration[0]
//             .children.variableDeclaratorList[0].children.variableDeclarator[0]
//             .children.variableDeclaratorId[0].children.Identifier[0].image;
//
//         classAst.fields.push({ name: name as string, type: type as string });
//       }
//     }
//   }
//   console.log(classAst);
// };
</script>
<style lang="sass" scoped>

.q-tabs--dense
  min-height: 0

.define
  background-color: red

.sticky
  position: sticky
  top: 0
  z-index: 1
/* 其他样式 */
</style>
